package cool.webstudy.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cool.webstudy.admin.constant.enums.DelFlagEnum;
import cool.webstudy.admin.constant.enums.EnabledStatusFlagEnum;
import cool.webstudy.admin.constant.enums.rescode.DictDataResCodeEnum;
import cool.webstudy.admin.constant.enums.rescode.DictTypeResCodeEnum;
import cool.webstudy.admin.exception.BusinessException;
import cool.webstudy.admin.mapper.dictData.DictDataMapper;
import cool.webstudy.admin.model.dto.dict.data.CreateDictDataDTO;
import cool.webstudy.admin.model.dto.dict.data.PaginationQueryDictDataDTO;
import cool.webstudy.admin.model.dto.dict.data.UpdateDictDataDTO;
import cool.webstudy.admin.model.dto.user.UserDetailInfoDTO;
import cool.webstudy.admin.model.po.dict.DictDataPO;
import cool.webstudy.admin.model.vo.dict.data.PaginationQueryDictDataVO;
import cool.webstudy.admin.model.vo.dict.data.QueryDictDataByDictTypeListVO;
import cool.webstudy.admin.service.DictDataService;
import cool.webstudy.admin.service.DictTypeService;
import cool.webstudy.admin.utils.UserDetailUtil;
import cool.webstudy.common.utils.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 作者：陈先生
 * 日期：2024/8/5
 * 描述:
 */
@Service
public class DictDataServiceImpl implements DictDataService {
    @Autowired
    private DictDataMapper dictDataMapper;
    @Autowired
    private DictTypeService dictTypeService;

    /**
     *
     * @param dto 创建字典值接口请求参数模型
     * @return 是否成功的标志
     * @description: 创建字典值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createDictData(CreateDictDataDTO dto) {
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();
        DictDataPO dictDataPO = new DictDataPO();
        dictDataPO.setParentUnCode(dto.getParentUnCode());
        dictDataPO.setCode(dto.getCode());
        dictDataPO.setName(dto.getName());
        dictDataPO.setValue(dto.getValue());
        dictDataPO.setDictTypeUnCode(dto.getDictTypeUnCode());
        dictDataPO.setIsDefault(dto.getIsDefault());

        dictDataPO.setCreateBy(userDetailInfo.getAccount());
        dictDataPO.setCreateTime(new Date());
        dictDataPO.setUpdateBy(userDetailInfo.getAccount());
        dictDataPO.setUpdateTime(new Date());
        dictDataPO.setStatusFlag(EnabledStatusFlagEnum.ENABLED);
        dictDataPO.setUnCode(UUIDUtil.getUUID());
        dictDataPO.setDelFlag(DelFlagEnum.NOT_DEL_FLAG.getFlag());
        try {
            dictDataMapper.insert(dictDataPO);
        }catch (Exception e){
            throw new BusinessException(DictTypeResCodeEnum.RC_ERROR_CREATE);
        }

        return true;
    }
    /**
     *
     * @param unCode 要删除的字典值的业务主键
     * @return 是否成功的标志
     * @description: 删除字典值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDictData(String unCode) {
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();
        LambdaUpdateWrapper<DictDataPO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(DictDataPO::getUnCode,unCode)
                .set(DictDataPO::getDelFlag,DelFlagEnum.DEL_FLAG.getFlag())
                .set(DictDataPO::getUpdateBy,userDetailInfo.getAccount())
                .set(DictDataPO::getUpdateTime,new Date());
        try {
            dictDataMapper.update(null,updateWrapper);
        }catch (BusinessException e){
            throw new BusinessException(DictDataResCodeEnum.RC_ERROR_DELETE);
        }
        return true;
    }
    /**
     * @param dictTypeUnCode 字典类型业务主键
     * @return Boolean 是否成功标识
     * @description: 根据字典类型业务主键来删除其下属的所有字典值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDictDataByDictTypeUnCode(String dictTypeUnCode) {
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();
        // 删除字典类型的时候，需要把该类型下的字典值一起删除
        LambdaUpdateWrapper<DictDataPO> updateDictDataWrapper = new LambdaUpdateWrapper<DictDataPO>();
        updateDictDataWrapper.eq(DictDataPO::getDictTypeUnCode, dictTypeUnCode)
                .set(DictDataPO::getDelFlag, DelFlagEnum.DEL_FLAG.getFlag())
                .set(DictDataPO::getUpdateBy, userDetailInfo.getAccount())
                .set(DictDataPO::getUpdateTime, new Date());
        return true;
    }

    /**
     *
     * @param dto 更新字典值接口请求参数模型
     * @return 是否成功的标志
     * @description: 更新字典值信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDictData(UpdateDictDataDTO dto) {
        UserDetailInfoDTO userDetailInfo = UserDetailUtil.getUserDetailInfo();

        LambdaUpdateWrapper<DictDataPO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(DictDataPO::getUnCode,dto.getUnCode())
                .set(DictDataPO::getCode,dto.getCode())
                .set(DictDataPO::getDictTypeUnCode,dto.getDictTypeUnCode())
                .set(DictDataPO::getName,dto.getName())
                .set(DictDataPO::getValue,dto.getValue())
                .set(DictDataPO::getParentUnCode,dto.getParentUnCode())
                .set(DictDataPO::getIsDefault,dto.getIsDefault())
                .set(DictDataPO::getUpdateBy,userDetailInfo.getAccount())
                .set(DictDataPO::getUpdateTime,new Date());
        try {
            dictDataMapper.update(null,updateWrapper);
        }catch (BusinessException e){
            throw new BusinessException(DictDataResCodeEnum.RC_ERROR_UPDATE);
        }
        return true;
    }
    /**
     *
     * @param dictType 字典类型
     * @return 是否成功的标志
     * @description: 根据字典类型查询字典值
     */
    @Override
    public List<QueryDictDataByDictTypeListVO> queryDictDataByDictTypeListVO(String dictType) {
        String dictTypeUnCode = dictTypeService.queryDictTypeUnCodeByDictType(dictType);
        if (StringUtils.isBlank(dictTypeUnCode)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<DictDataPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DictDataPO::getDictTypeUnCode, dictTypeUnCode)
                .eq(DictDataPO::getDelFlag,DelFlagEnum.NOT_DEL_FLAG.getFlag())
                .select(DictDataPO::getUnCode,DictDataPO::getParentUnCode,DictDataPO::getCode, DictDataPO::getName,DictDataPO::getValue,
                        DictDataPO::getDictTypeUnCode,DictDataPO::getIsDefault,DictDataPO::getStatusFlag);
        List<DictDataPO> dictDataPOList = dictDataMapper.selectList(queryWrapper);

        if(Objects.isNull(dictDataPOList)){
            return Collections.emptyList();
        }
        Map<String, String> dictTypeRoughInfoMap = dictTypeService.queryDictTypeRoughInfoMap();
        List<QueryDictDataByDictTypeListVO> queryDictDataByDictTypeVOList = new ArrayList<>();
        for (DictDataPO dictDataPO : dictDataPOList) {
            QueryDictDataByDictTypeListVO queryDictDataByDictTypeListVO = new QueryDictDataByDictTypeListVO();
            queryDictDataByDictTypeListVO.setUnCode(dictDataPO.getUnCode());
            queryDictDataByDictTypeListVO.setParentUnCode(dictDataPO.getParentUnCode());
            queryDictDataByDictTypeListVO.setCode(dictDataPO.getCode());
            queryDictDataByDictTypeListVO.setName(dictDataPO.getName());
            queryDictDataByDictTypeListVO.setValue(dictDataPO.getValue());
            queryDictDataByDictTypeListVO.setDictTypeUnCode(dictDataPO.getDictTypeUnCode());
            queryDictDataByDictTypeListVO.setDictTypeName(dictTypeRoughInfoMap.get(dictDataPO.getDictTypeUnCode()));
            queryDictDataByDictTypeListVO.setIsDefault(dictDataPO.getIsDefault());
            queryDictDataByDictTypeListVO.setStatusFlag(dictDataPO.getStatusFlag());
            queryDictDataByDictTypeListVO.setCreateBy(dictDataPO.getCreateBy());
            queryDictDataByDictTypeListVO.setCreateTime(dictDataPO.getCreateTime());
            queryDictDataByDictTypeListVO.setUpdateBy(dictDataPO.getUpdateBy());
            queryDictDataByDictTypeListVO.setUpdateTime(dictDataPO.getUpdateTime());
            queryDictDataByDictTypeVOList.add(queryDictDataByDictTypeListVO);
        }

        return queryDictDataByDictTypeVOList;
    }
    /**
     * @param dto 分页获取字典值信息列表接口请求参数模型
     * @return Page<PaginationQueryDictDataVO> 分页获取字典值信息列表接口响应参数模型
     * @description: 分页获取字典值信息列表接口
     */
    @Override
    public Page<PaginationQueryDictDataVO> paginationQueryDictDataByDictTypeListVO(PaginationQueryDictDataDTO dto) {
        Page<PaginationQueryDictDataVO> paginationQueryDictDataVOPage = new Page<>();
        Page<DictDataPO> page = new Page<>(dto.getCurrent(),dto.getPageSize());
        LambdaQueryWrapper<DictDataPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(dto.getContext()),DictDataPO::getCode,dto.getContext())
                .or().like(StringUtils.isNotBlank(dto.getContext()),DictDataPO::getValue,dto.getContext())
                .or().like(StringUtils.isNotBlank(dto.getContext()),DictDataPO::getName,dto.getContext())
                .eq(DictDataPO::getDictTypeUnCode,dto.getDictTypeUnCode());
        Page<DictDataPO> dictDataPOPage = dictDataMapper.selectPage(page,queryWrapper);
        if(Objects.isNull(dictDataPOPage)){
            return paginationQueryDictDataVOPage;
        }
        List<PaginationQueryDictDataVO> paginationQueryDictDataVOList = new ArrayList<>();
        dictDataPOPage.getRecords().forEach(dictDataPO -> {
            PaginationQueryDictDataVO dictDataVO = new PaginationQueryDictDataVO();
            dictDataVO.setUnCode(dictDataPO.getUnCode());
            dictDataVO.setParentUnCode(dictDataPO.getParentUnCode());
            dictDataVO.setDictTypeUnCode(dictDataPO.getDictTypeUnCode());
            dictDataVO.setCode(dictDataPO.getCode());
            dictDataVO.setName(dictDataPO.getName());
            dictDataVO.setValue(dictDataPO.getValue());
            dictDataVO.setIsDefault(dictDataPO.getIsDefault());
            dictDataVO.setStatusFlag(dictDataPO.getStatusFlag());
            dictDataVO.setCreateBy(dictDataPO.getCreateBy());
            dictDataVO.setCreateTime(dictDataPO.getCreateTime());
            dictDataVO.setUpdateBy(dictDataPO.getUpdateBy());
            dictDataVO.setUpdateTime(dictDataPO.getUpdateTime());
            paginationQueryDictDataVOList.add(dictDataVO);
        });
        paginationQueryDictDataVOPage.setRecords(paginationQueryDictDataVOList);
        paginationQueryDictDataVOPage.setCurrent(dictDataPOPage.getCurrent());
        paginationQueryDictDataVOPage.setPages(dictDataPOPage.getPages());
        paginationQueryDictDataVOPage.setSize(dictDataPOPage.getSize());
        paginationQueryDictDataVOPage.setTotal(dictDataPOPage.getTotal());
        return paginationQueryDictDataVOPage;
    }
}
